#include "Camera.hpp"
#include "Controller.hpp"
#include "GlWindow.hpp"
#include "UiUtil.hpp"
#include "ViewScene.hpp"

namespace UiUtil
{
   void WindowToWorld(Vec2 pos, Vec3& orig, Vec3& dir)
   {
      GlWindow* windowPtr = Controller::GetInstance().mGlWindow;
      float xScale(windowPtr->w() / 2.0f), yScale(-windowPtr->h()/2.0f);
      pos.x = pos.x / xScale - 1;
      pos.y = pos.y / yScale + 1; 
      ProjectionToWorld(pos, orig, dir);
   }
   void ProjectionToWorld(Vec2 pos, Vec3& orig, Vec3& dir)
   {
      Mat4 worldToScreen = ViewScene::GetInstance().mTransform.GetFullTransform();
      Mat4 screenToWorld = worldToScreen.inverse();
      Vec3 cursor(pos.x, pos.y, 1.0f);
      orig = Controller::GetInstance().GetCamera()->mViewPoint.Origin();
      cursor = screenToWorld * cursor;
      dir = cursor - orig;
   }
   void WorldToProjection(Vec3 pos, Vec3& projected)
   {
      Mat4 project = ViewScene::GetInstance().mTransform.GetFullTransform();
      Vec3 cursor(pos.x, pos.y, 1.0f);
      projected = project * pos;
   }
   void WorldToWindow(Vec3 pos, Vec3& projected)
   {
      WorldToProjection(pos, projected);
      GlWindow* windowPtr = Controller::GetInstance().mGlWindow;
      float xScale(windowPtr->w() / 2.0f), yScale(-windowPtr->h()/2.0f);
      projected.x = (projected.x + 1) * xScale;
      projected.y = (projected.y - 1) * yScale; 
   }
   void ScreenToProjection(Vec3 pos, Vec3& projected)
   {
      GlWindow* windowPtr = Controller::GetInstance().mGlWindow;
      float xScale(windowPtr->w() / 2.0f), yScale(-windowPtr->h()/2.0f);
      projected.x = pos.x / xScale - 1;
      projected.y = pos.y / yScale + 1;
      projected.z = pos.z;
   }
}
